/**
 * Used to monitor routing changes to change the status of menus and tabs. There is no need to monitor the route, because the route status change is affected by the page rendering time, which will be slow
 */

import { mitt } from '/@/utils/mitt';
import type { RouteLocationNormalized } from 'vue-router';
import { getRawRoute } from '/@/utils';

const emitter = mitt();

//使用 Symbol 作为键的一个主要好处是防止属性名的冲突，特别是当你使用一个第三方的对象，而你需要添加新属性，又不想修改或干扰该对象已有属性的时候。
//此外，Symbol 属性不会出现在常规的对象属性枚举中，例如 for...in 循环或 Object.keys() 方法，这提供了一种隐藏对象属性的机制。
const key = Symbol();

let lastChangeTab: RouteLocationNormalized;

/**
 * 设置路由变更并触发事件
 *
 * @param {RouteLocationNormalized} lastChangeRoute - 上次变更的路由对象
 */
export function setRouteChange(lastChangeRoute: RouteLocationNormalized) {
  // 获取原始的路由对象
  const r = getRawRoute(lastChangeRoute);

  // 触发事件，传递原始的路由对象
  emitter.emit(key, r);

  // 更新上次变更的路由对象
  lastChangeTab = r;
}

/**
 * 监听路由变更并执行回调函数
 *
 * @param {Function} callback - 路由变更时执行的回调函数，接收一个 `RouteLocationNormalized` 类型的参数
 * @param {boolean} [immediate=true] - 是否在添加监听时立即执行回调函数，默认为 `true`
 */
export function listenerRouteChange(
  callback: (route: RouteLocationNormalized) => void,
  immediate = true,
) {
  // 注册事件监听器，当路由发生变化时执行回调函数
  emitter.on(key, callback);

  // 如果 `immediate` 为 `true`，且上次的路由变更记录存在，则立即执行回调函数
  immediate && lastChangeTab && callback(lastChangeTab);
}

export function removeTabChangeListener() {
  emitter.clear();
}
